using System;
using Glue;
using GlueTests.Builders;
using Xunit;

namespace GlueTests.AutoRelaterTests
{
    public class When_automatically_relating_ReadOnly_or_WriteOnly_properties
    {
        private readonly Mapping<DomainPerson, GuiPerson> mapping;

        public class DomainPerson
        {
            public int Id { get; private set; }
            public String Name { get; set; }
            public bool Ignore { private get; set; }
            public bool ReadOnly { get; private set; }
        }
        public class GuiPerson
        {
            public int Id { get; set; }
            public String Name { private get; set; }
            public bool Ignore { private get; set; }
            public bool ReadOnly { get; private set; }
        }

        public When_automatically_relating_ReadOnly_or_WriteOnly_properties()
        {
            mapping = new Mapping<DomainPerson, GuiPerson>();
            mapping.AutoRelateEqualNames();
        }

        [Fact]
        public void Should_not_relate_towards_readonly_property()
        {
            Assert.False(IsRelatedTowardsOnLeftSide("Id"));
        }

        [Fact]
        public void Should_relate_from_readonly_property()
        {
            Assert.True(IsRelatedTowardsOnRighttSide("Id"));
        }

        [Fact]
        public void Should_not_relate_from_writeonly_property()
        {
            Assert.False(IsRelatedTowardsOnLeftSide("Name"));
        }

        [Fact]
        public void Should_not_relate_to_writeonly_property()
        {
            Assert.False(IsRelatedTowardsOnRighttSide("Name"));
        }

        [Fact]
        public void Should_not_relate_anything_when_both_properties_are_WriteOnly()
        {
            Assert.False(IsRelatedTowardsOnLeftSide("Ignore"));
            Assert.False(IsRelatedTowardsOnRighttSide("Ignore"));
        }

        [Fact]
        public void Should_not_relate_anything_when_both_properties_are_ReadOnly()
        {
            Assert.False(IsRelatedTowardsOnLeftSide("ReadOnly"));
            Assert.False(IsRelatedTowardsOnRighttSide("ReadOnly"));
        }

        private bool IsRelatedTowardsOnLeftSide(string propertyName)
        {
            return mapping.Relations.IsRelatedTowardsOnLeftSide(new PropertyBuilder(typeof(DomainPerson), propertyName).Build());
        }

        private bool IsRelatedTowardsOnRighttSide(string propertyName)
        {
            return mapping.Relations.IsRelatedTowardsOnRightSide(new PropertyBuilder(typeof(GuiPerson), propertyName).Build());
        }
    }
}